package io.jpress.commons.ip2region;

import com.jfinal.kit.PathKit;
import com.jfinal.log.Log;
import io.jboot.Jboot;
import io.jboot.app.JbootApplication;
import io.jboot.utils.FileUtil;
import io.jboot.utils.StrUtil;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbMakerConfigException;
import org.lionsoul.ip2region.DbSearcher;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Ip2RegionUtil {

    private static final Log LOG = Log.getLog(Ip2RegionUtil.class);
    private static DbSearcher searcher;

    static {
        init();
    }

    public static void init() {
        try {
            boolean dbExists = false;
            String resourcePath = Jboot.configValue("jboot.ip2region.path");
            if (StrUtil.isNotBlank(resourcePath)) {
                File file = new File(resourcePath);
                if (file.exists()) {
                    resourcePath = FileUtil.getCanonicalPath(file);
                    dbExists = true;
                }

                if (!dbExists) {
                    file = new File(PathKit.getRootClassPath(), resourcePath);
                    if (file.exists()) {
                        resourcePath = FileUtil.getCanonicalPath(file);
                        dbExists = true;
                    }
                }
            }

            if (!dbExists) {
                File file = new File(PathKit.getRootClassPath(), "ip2region.db");
                if (file.exists()) {
                    resourcePath = FileUtil.getCanonicalPath(file);
                    dbExists = true;
                }
            }

            if (!dbExists) {
                File file = new File(PathKit.getRootClassPath(), "ip2region/ip2region.db");
                if (file.exists()) {
                    resourcePath = FileUtil.getCanonicalPath(file);
                    dbExists = true;
                }
            }

            if (dbExists) {
                DbConfig config = new DbConfig();
                searcher = new DbSearcher(config, resourcePath);
            }
        } catch (DbMakerConfigException | FileNotFoundException e) {
            LOG.error(e.toString(), e);
        }
    }

    /**
     * ip 位置 搜索
     *
     * @param ip ip
     * @return 位置
     */
    public static IpInfo memorySearch(long ip) {
        try {
            return searcher != null ? new IpInfo(searcher.memorySearch(ip)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    /**
     * ip 位置 搜索
     *
     * @param ip ip
     * @return 位置
     */
    public static IpInfo memorySearch(String ip) {
        try {
            return searcher != null ? new IpInfo(searcher.memorySearch(ip)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    /**
     * ip 位置 搜索
     *
     * @param ptr ptr
     * @return 位置
     */
    public static IpInfo getByIndexPtr(long ptr) {
        try {
            return searcher != null ? new IpInfo(searcher.getByIndexPtr(ptr)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    /**
     * ip 位置 搜索
     *
     * @param ip ip
     * @return 位置
     */
    public static IpInfo btreeSearch(long ip) {
        try {
            return searcher != null ? new IpInfo(searcher.btreeSearch(ip)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    /**
     * ip 位置 搜索
     *
     * @param ip ip
     * @return 位置
     */
    public static IpInfo btreeSearch(String ip) {
        try {
            return searcher != null ? new IpInfo(searcher.btreeSearch(ip)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    /**
     * ip 位置 搜索
     *
     * @param ip ip
     * @return 位置
     */
    public static IpInfo binarySearch(long ip) {
        try {
            return searcher != null ? new IpInfo(searcher.binarySearch(ip)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    /**
     * ip 位置 搜索
     *
     * @param ip ip
     * @return 位置
     */
    public static IpInfo binarySearch(String ip) {
        try {
            return searcher != null ? new IpInfo(searcher.binarySearch(ip)) : null;
        } catch (IOException e) {
            LOG.error(e.toString(), e);
        }
        return null;
    }

    public static void main(String[] args) {
        JbootApplication.setBootArg("jboot.ip2region.path", "/Users/michael/work/git/JPressPro/jpress-commons/src/main/resources/ip2region.db");
        Ip2RegionUtil.init();
        System.out.println(Ip2RegionUtil.binarySearch("127.0.0.1"));
        System.out.println(Ip2RegionUtil.binarySearch("1.207.70.165"));
        System.out.println(Ip2RegionUtil.binarySearch("123.125.71.38"));
    }

}
